﻿using System;

namespace Borg
{
    [Serializable]
    public class Plug : MetaElement
    {
        private Extension _extension;
        private PlugType _plugType;

        internal bool autoPlug;
        internal string[] autoTag;

        private MetaElementCollection<Param> _params;

        internal MetaElementCollection<Slot> slotsWherePlugged;

        public Extension Extension
        {
            get { return _extension; }
            private set { _extension = value; }
        }

        public PlugType PlugType
        {
            get { return _plugType; }
            private set { _plugType = value; }
        }

        public bool AutoPlug
        {
            get { return InstanceStore.GetAutoPlug(this); }
            set { Composer.SetAutoPlug(this, value); }
        }

        public string[] AutoTag
        {
            get { return InstanceStore.GetAutoTag(this); }
            set { Composer.SetAutoTag(this, value); }
        }

        public MetaElementCollection<Param> Params
        {
            get { return _params; }
            internal set { _params = value; }
        }

        public MetaElementCollection<Slot> SlotsWherePlugged
        {
            get { return InstanceStore.GetSlotsWherePlugged(this); }
        }

        public MetaElementCollection<Tag> TaggedTags
        {
            get { return InstanceStore.GetTags(this); }
        }

        public event EventHandler<CompositionEventArgs> Plugging
        {
            add { Notifier.AddPluggingHandler(this, value); }
            remove { Notifier.RemovePluggingHandler(this, value); }
        }

        public event EventHandler<CompositionEventArgs> Plugged
        {
            add { Notifier.AddPluggedHandler(this, value); }
            remove { Notifier.RemovePluggedHandler(this, value); }
        }

        public event EventHandler<TagEventArgs> Tagging
        {
            add { Notifier.AddTaggingHandler(this, value); }
            remove { Notifier.RemoveTaggingHandler(this, value); }
        }

        public event EventHandler<TagEventArgs> Tagged
        {
            add { Notifier.AddTaggedHandler(this, value); }
            remove { Notifier.RemoveTaggedHandler(this, value); }
        }

        public event EventHandler<CompositionEventArgs> Unplugging
        {
            add { Notifier.AddUnpluggingHandler(this, value); }
            remove { Notifier.RemoveUnpluggingHandler(this, value); }
        }

        public event EventHandler<CompositionEventArgs> Unplugged
        {
            add { Notifier.AddUnpluggedHandler(this, value); }
            remove { Notifier.RemoveUnpluggedHandler(this, value); }
        }

        public event EventHandler<TagEventArgs> Untagging
        {
            add { Notifier.AddUntaggingHandler(this, value); }
            remove { Notifier.RemoveUntaggingHandler(this, value); }
        }

        public event EventHandler<TagEventArgs> Untagged
        {
            add { Notifier.AddUntaggedHandler(this, value); }
            remove { Notifier.RemoveUntaggedHandler(this, value); }
        }

        internal Plug(int id, PlugType plugType, Extension extension)
            : base(id, plugType.Name)
        {
            Extension = extension;
            PlugType = plugType;
            
            slotsWherePlugged = new MetaElementCollection<Slot>();
            
            Composer.InternalSetAutoPlug(this, plugType.AutoPlug);
            Composer.InternalSetAutoTag(this, plugType.AutoTag);
        }

        internal override AssemblyElement GetAssemblyElement()
        {
            return Extension.ExtensionType.Plugin;
        }
    }
}

